/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package korekosystem.vista;

import java.awt.Point;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.NoResultException;
import javax.persistence.Persistence;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.swing.JOptionPane;
import javax.swing.ListSelectionModel;
import javax.swing.event.InternalFrameAdapter;
import javax.swing.event.InternalFrameEvent;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import korekosystem.modelo.Cliente;
import net.coderazzi.filters.gui.TableFilterHeader;
import korekosystem.JTextFieldLimit;

/**
 *
 * @author Santiago
 */
public class ABMCliente extends javax.swing.JInternalFrame {

    @PersistenceContext
    EntityManager entityMgr;
    
    Cliente cliente;
    boolean multipleSeleccion;
    /**
     * Creates new form ABMCliente
     */
    public ABMCliente() {
        initComponents();
        nombreText.setDocument(new JTextFieldLimit(30));
        apellidoText.setDocument(new JTextFieldLimit(30));
        direccionText.setDocument(new JTextFieldLimit(60));
        TableFilterHeader filterHeader = new TableFilterHeader(jTable1);
        
        this.addInternalFrameListener(new InternalFrameAdapter() {
            
            // Cierra el entityManager cuando se cierra
            // la ventana
            @Override
            public void internalFrameClosed(InternalFrameEvent ev) {
                if (entityMgr != null && entityMgr.isOpen()) {
                    entityMgr.close();
                }
            }
            // Se reescribe el evento cuando se abre la ventana
            // para que instancie el entityManager
            @Override
            public void internalFrameOpened(InternalFrameEvent ev) {
                ABMCliente estaVentana =
                        (ABMCliente) ev.getSource();
                try {
                    entityMgr = Persistence
                            .createEntityManagerFactory("KorekoSystemPU")
                            .createEntityManager();
                    estaVentana.recargarTabla();
                } catch (Exception e) {
                    JOptionPane.showMessageDialog(estaVentana,
                            "Error al inciar el motor de persistencia\n [" +
                            e.getMessage() + "]");
                    estaVentana.dispose();
                }
            }
        });
        
        
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        jLabel4 = new javax.swing.JLabel();
        jLabel5 = new javax.swing.JLabel();
        nombreText = new javax.swing.JTextField();
        apellidoText = new javax.swing.JTextField();
        direccionText = new javax.swing.JTextField();
        telefono1Text = new javax.swing.JFormattedTextField();
        telefono2Text = new javax.swing.JFormattedTextField();
        jScrollPane1 = new javax.swing.JScrollPane();
        jTable1 = new javax.swing.JTable();
        guardarButton = new javax.swing.JButton();
        eliminarButton = new javax.swing.JButton();

        setClosable(true);
        setIconifiable(true);
        setMaximizable(true);
        setTitle("ABMCliente");

        jPanel1.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        jLabel1.setText("Nombre:");

        jLabel2.setText("Apellido:");

        jLabel3.setText("Dirección:");

        jLabel4.setText("Teléfono 1:");

        jLabel5.setText("Teléfono 2:");

        nombreText.setHorizontalAlignment(javax.swing.JTextField.LEFT);
        nombreText.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
        nombreText.setNextFocusableComponent(apellidoText);

        apellidoText.setHorizontalAlignment(javax.swing.JTextField.LEFT);
        apellidoText.setNextFocusableComponent(direccionText);

        direccionText.setNextFocusableComponent(telefono1Text);

        try {
            telefono1Text.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.MaskFormatter("####-###-###")));
        } catch (java.text.ParseException ex) {
            ex.printStackTrace();
        }
        telefono1Text.setFocusLostBehavior(javax.swing.JFormattedTextField.PERSIST);
        telefono1Text.setNextFocusableComponent(telefono2Text);

        try {
            telefono2Text.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.MaskFormatter("####-###-###")));
        } catch (java.text.ParseException ex) {
            ex.printStackTrace();
        }
        telefono2Text.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
        telefono2Text.setFocusLostBehavior(javax.swing.JFormattedTextField.PERSIST);
        telefono2Text.setNextFocusableComponent(guardarButton);

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel2)
                    .addComponent(jLabel3)
                    .addComponent(jLabel1))
                .addGap(10, 10, 10)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                    .addComponent(apellidoText, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 257, Short.MAX_VALUE)
                    .addComponent(nombreText, javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(direccionText))
                .addGap(18, 18, 18)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel5)
                    .addComponent(jLabel4))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(telefono1Text)
                    .addComponent(telefono2Text))
                .addContainerGap())
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
                    .addComponent(nombreText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel1)
                    .addComponent(jLabel4)
                    .addComponent(telefono1Text, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel2)
                    .addComponent(jLabel5)
                    .addComponent(apellidoText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(telefono2Text, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel3)
                    .addComponent(direccionText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(19, Short.MAX_VALUE))
        );

        jScrollPane1.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        jTable1.setAutoCreateRowSorter(true);
        jTable1.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {
                "", "id", "Nombres", "Apellidos", "Dirección", "Teléfono 1", "Teléfono 2", "Saldo"
            }
        ) {
            Class[] types = new Class [] {
                java.lang.Boolean.class, java.lang.Integer.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Long.class
            };
            boolean[] canEdit = new boolean [] {
                true, false, false, false, false, false, false, false
            };

            public Class getColumnClass(int columnIndex) {
                return types [columnIndex];
            }

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
        });
        jTable1.getTableHeader().setReorderingAllowed(false);
        jTable1.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jTable1MouseClicked(evt);
            }
        });
        jScrollPane1.setViewportView(jTable1);
        jTable1.getColumnModel().getColumn(0).setMinWidth(40);
        jTable1.getColumnModel().getColumn(0).setPreferredWidth(40);
        jTable1.getColumnModel().getColumn(0).setMaxWidth(40);

        guardarButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/recursos/guardar.png"))); // NOI18N
        guardarButton.setText("Guardar");
        guardarButton.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                guardarButtonMouseClicked(evt);
            }
        });

        eliminarButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/recursos/eliminar.png"))); // NOI18N
        eliminarButton.setText("Eliminar");
        eliminarButton.setEnabled(false);
        eliminarButton.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                eliminarButtonMouseClicked(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 614, Short.MAX_VALUE)
                    .addComponent(jPanel1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addGap(0, 0, Short.MAX_VALUE)
                        .addComponent(guardarButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(eliminarButton)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 293, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(guardarButton)
                    .addComponent(eliminarButton))
                .addGap(8, 8, 8))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void jTable1MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jTable1MouseClicked
        
        // La salsa y el fideo a full aca, cuidado cuidado...
        // apartir de este salto de linea, usted entra en un universo alterno
        
        // esto sirve para que efectivamente tome en cuenta solo los
        // clicks en la primera columna (la columna de seleccion)
        Point p = evt.getPoint();
        if (jTable1.columnAtPoint(p) == 0){
            // Recorremos toda la tabla, buscando los seleccionados
            // guardamos el numero de elementos seleccionados
            // si es uno solo, cargamos en cliente.
            TableModel tm = jTable1.getModel();
            int selectcount = 0;
            int selectindex = 0;
            for (int i=0; i < tm.getRowCount(); i++ ){
                if( (Boolean) tm.getValueAt(i, 0) == true){
                    selectcount++;
                    selectindex = i;
                }

            }

            if(selectcount == 1){
                Integer id = new Integer(tm.getValueAt(selectindex, 1).toString());

                if ( entityMgr.isOpen()) {
                    try {
                        Query q = entityMgr
                                .createQuery("select o from Cliente o " +
                                        "where trim(o.id) = :codigo");
                        q.setParameter("codigo", id.toString());
                        cliente = (Cliente) q.getSingleResult();
                        // puede que el objeto no esté sincronizado con la bd
                        entityMgr.refresh(cliente);

                    }
                    catch (NoResultException  ignorada) {}
                    catch (Exception e) {
                        JOptionPane.showMessageDialog(this, "Error del sistema: [" +
                                e.getMessage() + "]");
                        e.printStackTrace();
                    }
                }
                
                this.limpiarFormulario();
                this.rellenarCampos();
                eliminarButton.setEnabled(true);
                multipleSeleccion = false;
                
            //si no hay nada seleccionado, limpiamos el formulario
            }else if (selectcount == 0){
                eliminarButton.setEnabled(false);
                limpiarFormulario();
                cliente = null;
                multipleSeleccion = false;
            //mas de 1...
            }else{
                eliminarButton.setEnabled(true);
                limpiarFormulario();
                cliente = null;
                multipleSeleccion = true;
            }
        }
            
    }//GEN-LAST:event_jTable1MouseClicked

    private void guardarButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_guardarButtonMouseClicked
        // Avisamos que ciertos campos no pueden ser nulos
        if(nombreText.getText() == null || nombreText.getText().trim().equals("")) {
            JOptionPane.showMessageDialog(this, "El nombre no puede ser nulo");
            nombreText.requestFocus();
            return;
        } else if(apellidoText.getText() == null || 
                apellidoText.getText().trim().equals("")) {
            JOptionPane.showMessageDialog(this, "El apellido no puede ser nulo");
            apellidoText.requestFocus();
            return;
        }
        
        
        EntityTransaction tr = null;
        try {
            tr = entityMgr.getTransaction();
            tr.begin();
            // si el id de la bd es nulo el objeto no existe
            if (cliente == null) {
                cliente = new Cliente();
                cliente.setNombre(nombreText.getText());
                cliente.setApellido(apellidoText.getText());
                cliente.setTelefono1(telefono1Text.getText());
                cliente.setTelefono2(telefono2Text.getText());
                cliente.setDireccion(direccionText.getText());
                cliente.setActivo(true);
                entityMgr.persist(cliente);
            } else {
                cliente.setNombre(nombreText.getText());
                cliente.setApellido(apellidoText.getText());
                cliente.setTelefono1(telefono1Text.getText());
                cliente.setTelefono2(telefono2Text.getText());
                cliente.setDireccion(direccionText.getText());
                cliente.setActivo(true);
                entityMgr.merge(cliente);   
            }
            tr.commit();
            JOptionPane.showMessageDialog(this, "Cambios guardados con exito!");
            
        } catch (Exception e) {
            if (tr != null && tr.isActive()) {
                tr.rollback();
            }
            JOptionPane.showMessageDialog(this, "Error del sistema: [" +
                        e.getMessage() + "]");
            e.printStackTrace();
        }finally{
            cliente = null;
            limpiarFormulario();
            recargarTabla();
            eliminarButton.setEnabled(false);
        }
    }//GEN-LAST:event_guardarButtonMouseClicked

    private void eliminarButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_eliminarButtonMouseClicked
        // Acciones para cuando se hace Click en Eliminar
        if(cliente != null || multipleSeleccion) {
            int r = JOptionPane.showConfirmDialog(this, "Esta seguro de " +
                    "borrar los datos", "Atencion", JOptionPane.YES_NO_OPTION);
            if (r == JOptionPane.NO_OPTION) {
                return;
            }
            
            EntityTransaction tr = null;
            try {
                tr = entityMgr.getTransaction();
                tr.begin();
                if(!multipleSeleccion){
                    cliente.setActivo(false);
                    entityMgr.merge(cliente);
                    
                }else{
                    List<Cliente> lista = devolverSeleccionados();
                    for (Cliente c : lista){
                        c.setActivo(false);
                        entityMgr.merge(c);
                    }
                }
                
                tr.commit();
            }
            catch (Exception e) {
                if (tr != null && tr.isActive()) {
                   tr.rollback();
                }                
                JOptionPane.showMessageDialog(this, "Error del sistema: [" +
                    e.getMessage() + "]");
                e.printStackTrace();
                
            } finally{
                //cliente = null;
                limpiarFormulario();
                recargarTabla();
            }
        }
        
    }//GEN-LAST:event_eliminarButtonMouseClicked

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JTextField apellidoText;
    private javax.swing.JTextField direccionText;
    private javax.swing.JButton eliminarButton;
    private javax.swing.JButton guardarButton;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTable jTable1;
    private javax.swing.JTextField nombreText;
    private javax.swing.JFormattedTextField telefono1Text;
    private javax.swing.JFormattedTextField telefono2Text;
    // End of variables declaration//GEN-END:variables


    //aca empiezan los metodos nuestros
    public void recargarTabla(){
        try{
            Query q = entityMgr.createNamedQuery("Cliente.findByActivo");
            List<Cliente> result = q.getResultList();
            // se obtiene la referencia al modelo de datos
            DefaultTableModel tm = ((DefaultTableModel)jTable1.getModel());
            // se descartan la filas existentes
            tm.setRowCount(0);

            // se añaden los datos obtenidos si es que existen
            // cada fila recuperada es un array de Object[]
            System.out.println("Ya tengo los resultados supuestamente");
            for (Cliente o : result) {
                System.out.println("-->"+o);
                // Agregamos a un vector las propiedades
                Vector v = new Vector();
                v.add(false);
                v.add(o.getId());
                v.add(o.getNombre());
                v.add(o.getApellido());
                v.add(o.getDireccion());
                v.add(o.getTelefono1());
                v.add(o.getTelefono2());
                v.add(o.getSaldo());
                // Agregamos ese vector como columna
                tm.addRow(v);
            }
        }catch(Exception e){
            JOptionPane.showMessageDialog(this,
                            "Error en el sistema\n [" +
                            e.getMessage() + "]");
                    this.dispose();
        }
    }

    private void rellenarCampos() {
        if (cliente != null && cliente.getId() != null ){
            this.nombreText.setText(cliente.getNombre());
            this.apellidoText.setText(cliente.getApellido());
            this.direccionText.setText(cliente.getDireccion());
            this.telefono1Text.setText(cliente.getTelefono1());
            this.telefono2Text.setText(cliente.getTelefono2());
            
        }
    }

    private void limpiarFormulario() {
            this.nombreText.setText("");
            this.apellidoText.setText("");
            this.direccionText.setText("");
            this.telefono1Text.setText("");
            this.telefono2Text.setText("");
    }
    
    private List<Cliente> devolverSeleccionados(){
        TableModel tm = jTable1.getModel();
        ArrayList<Cliente> lista = new ArrayList();
        for (int i=0; i < tm.getRowCount(); i++ ){
                if( (Boolean) tm.getValueAt(i, 0) == true){
                    Integer id = new Integer(tm.getValueAt(i, 1).toString());

                    if ( entityMgr.isOpen()) {
                        try {
                            Query q = entityMgr
                                    .createQuery("select o from Cliente o " +
                                            "where trim(o.id) = :codigo");
                            q.setParameter("codigo", id.toString());
                            lista.add( (Cliente) q.getSingleResult() );

                        }
                        catch (NoResultException  ignorada) {}
                        catch (Exception e) {
                            JOptionPane.showMessageDialog(this, "Error del sistema: [" +
                                    e.getMessage() + "]");
                            e.printStackTrace();
                        }
                    }

            }
        }
        return lista;
    }
}
